package de.lgohlke.helper;

import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * simply moves the date in the future or in the past
 *
 * @author lars
 * @version $Id: $
 */
public class DateCalculator
{
	enum DISTANCE
	{
		EARLIER()
		{
			@Override
			protected Date calculate(Calendar cal, int duration, TimeUnit unit)
			{
				cal.add(Calendar.SECOND, -1 * (int) TimeUnit.SECONDS.convert(duration, unit));

				return cal.getTime();
			}

		},
		LATER()
		{
			@Override
			protected Date calculate(Calendar cal, int duration, TimeUnit unit)
			{
				cal.add(Calendar.SECOND, (int) TimeUnit.SECONDS.convert(duration, unit));

				return cal.getTime();
			}
		};

		protected abstract Date calculate(Calendar cal, int duration, TimeUnit unit);

		public Date calculate(Date date, int duration, TimeUnit unit)
		{
			Calendar cal = Calendar.getInstance();
			cal.setTime(date);

			// Date before = cal.getTime();
			Date after = calculate(cal, duration, unit);

			return after;
		}
	}

	private Date	date;

	/**
	 * <p>Constructor for DateCalculator.</p>
	 *
	 * @param d1 a {@link java.util.Date} object.
	 */
	public DateCalculator(Date d1)
	{
		this.date = d1;
	}

	/**
	 * subtract some time and pull the current date in the past (relativly)
	 *
	 * @param duration a int.
	 * @param unit a {@link java.util.concurrent.TimeUnit} object.
	 * @return a {@link de.lgohlke.helper.DateCalculator} object.
	 */
	public DateCalculator earlier(int duration, TimeUnit unit)
	{
		date = DISTANCE.EARLIER.calculate(date, duration, unit);

		return this;
	}

	/**
	 * <p>Getter for the field <code>date</code>.</p>
	 *
	 * @return a {@link java.util.Date} object.
	 */
	public Date getDate()
	{
		return date;
	}

	/**
	 * add some time and push the current date in the future
	 *
	 * @param duration a int.
	 * @param unit a {@link java.util.concurrent.TimeUnit} object.
	 * @return a {@link de.lgohlke.helper.DateCalculator} object.
	 */
	public DateCalculator later(int duration, TimeUnit unit)
	{
		date = DISTANCE.LATER.calculate(date, duration, unit);

		return this;
	}
}
